package repository

import (
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
	"gitee.com/fierce_wolf/go-fox-edge-common/commEntityManager"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/String"
	"gitee.com/fierce_wolf/go-fox-edge-common/edgeEntity"
)

type repoLocalApplicationService struct {
}

func (e *repoLocalApplicationService) updateRepoCompEntityByAppType(appType string) {
	serviceConfList := LocalAppConf.readConfFileType(appType)

	for _, serviceConf := range serviceConfList {
		e.updateRepoCompEntityByConf(serviceConf)
	}
}

func (e *repoLocalApplicationService) updateRepoCompEntity(appType, appName string) error {
	serviceConf, err := LocalAppConf.readConfFileTypeName(appType, appName)
	if err != nil {
		return err
	}

	return e.updateRepoCompEntityByConf(serviceConf)
}

func (e *repoLocalApplicationService) buildRepoCompEntityByConf(serviceConf map[string]interface{}) (*edgeEntity.RepoCompEntity, error) {
	localMap, err := LocalCompConvert.ConvertConf2Local(serviceConf)
	if err != nil {
		return nil, err
	}

	entity, err := LocalCompBuilder.BuildCompEntity(localMap)
	if err != nil {
		return nil, err
	}

	return entity, err
}

func (e *repoLocalApplicationService) updateRepoCompEntityByConf(serviceConf map[string]interface{}) error {
	newEntity, err := e.buildRepoCompEntityByConf(serviceConf)
	if err != nil {
		return err
	}

	existEntity := commEntityManager.FindEntity(edgeEntity.Type.RepoCompEntity.Type(), func(value commEntity.IEntity) bool {
		compEntity := value.(*edgeEntity.RepoCompEntity)

		if compEntity.CompRepo != "local" {
			return false
		}
		if compEntity.CompType != "app-service" {
			return false
		}
		if newEntity.CompName != compEntity.CompName {
			return false
		}

		return true
	})

	e.updateRepoCompEntityByEntity(newEntity, existEntity)
	return nil
}

func (e *repoLocalApplicationService) updateRepoCompEntityByEntity(updateEntity *edgeEntity.RepoCompEntity, existEntity commEntity.IEntity) {
	if updateEntity == nil {
		return
	}

	if existEntity == nil {
		commEntityManager.InsertEntity(updateEntity)
		return
	}

	srcEntity := updateEntity
	dstEntity := existEntity.(*edgeEntity.RepoCompEntity)

	srcSB := ""
	srcSB += Map.GetString(srcEntity.CompParam, "appEngine", "")
	srcSB += Map.GetString(srcEntity.CompParam, "appName", "")
	srcSB += Map.GetString(srcEntity.CompParam, "appType", "")
	srcSB += Map.GetString(srcEntity.CompParam, "fileName", "")
	srcSB += Map.GetString(srcEntity.CompParam, "loaderName", "")
	srcSB += Map.GetString(srcEntity.CompParam, "userParam", "")
	srcSB += String.ToString(Map.GetOrDefault(srcEntity.CompParam, "confFiles", make([]string, 0)))

	dstSB := ""
	dstSB += Map.GetString(srcEntity.CompParam, "appEngine", "")
	dstSB += Map.GetString(srcEntity.CompParam, "appName", "")
	dstSB += Map.GetString(srcEntity.CompParam, "appType", "")
	dstSB += Map.GetString(srcEntity.CompParam, "fileName", "")
	dstSB += Map.GetString(srcEntity.CompParam, "loaderName", "")
	dstSB += Map.GetString(srcEntity.CompParam, "userParam", "")
	dstSB += String.ToString(Map.GetOrDefault(srcEntity.CompParam, "confFiles", make([]string, 0)))

	if dstSB == srcSB {
		return
	}

	// 修改内容
	e.setDefault(srcEntity.CompParam, dstEntity.CompParam, "appName")
	e.setDefault(srcEntity.CompParam, dstEntity.CompParam, "appEngine")
	e.setDefault(srcEntity.CompParam, dstEntity.CompParam, "appType")
	e.setDefault(srcEntity.CompParam, dstEntity.CompParam, "fileName")
	e.setDefault(srcEntity.CompParam, dstEntity.CompParam, "loaderName")
	e.setDefault(srcEntity.CompParam, dstEntity.CompParam, "userParam")
	e.setDefault(srcEntity.CompParam, dstEntity.CompParam, "confFiles")

	commEntityManager.UpdateEntity(srcEntity)
}

func (e *repoLocalApplicationService) setDefault(update, exist map[string]interface{}, key string) {
	if Map.Has(update, key) {
		return
	}

	update[key] = exist[key]
}

func (e *repoLocalApplicationService) Sort(entityList []commEntity.IEntity) []commEntity.IEntity {
	resultList := make([]commEntity.IEntity, 0)

	// 先进行数组的排序
	commEntity.SortEntityList(entityList)

	// 然后再按分类排序
	for _, entity := range entityList {
		compEntity := entity.(*edgeEntity.RepoCompEntity)

		if compEntity.CompType != "app-service" {
			resultList = append(resultList, compEntity)
		}
	}

	for _, entity := range entityList {
		compEntity := entity.(*edgeEntity.RepoCompEntity)

		if compEntity.CompType != "app-service" {
			continue
		}

		appType := Map.GetString(compEntity.CompParam, "appType", "")
		if appType == "kernel" {
			resultList = append(resultList, compEntity)
			continue
		}
	}

	for _, entity := range entityList {
		compEntity := entity.(*edgeEntity.RepoCompEntity)

		if compEntity.CompType != "app-service" {
			continue
		}

		appType := Map.GetString(compEntity.CompParam, "appType", "")
		if appType == "system" {
			resultList = append(resultList, compEntity)
			continue
		}
	}

	for _, entity := range entityList {
		compEntity := entity.(*edgeEntity.RepoCompEntity)

		if compEntity.CompType != "app-service" {
			continue
		}

		appType := Map.GetString(compEntity.CompParam, "appType", "")
		if appType == "service" {
			resultList = append(resultList, compEntity)
			continue
		}
	}

	return resultList
}
